import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.EmptyBorder;

public class Panel extends JPanel {
	private static final long serialVersionUID = 2782740346351480707L;

	// 计算器输入文本框
	private static JTextArea text;
	// 计算器按钮面板
	private static JPanel panel;

	public Panel() {
		setOpaque(false);
		setBorder(new EmptyBorder(5, 5, 5, 5));

		setTextArea();
		setPanel();
		setContentLayout();
	}

	// 文本框处理
	private void setTextArea() {
		text = new JTextArea();
		text.setOpaque(false);
		text.setFont(new Font("微软雅黑", Font.BOLD, 14));
		text.setLineWrap(true);
		text.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				// 计算算术表达式
				if (e.getKeyChar() == '=') {
					calculate();
				}
				// 替换键盘'*'为'×'
				if (e.getKeyChar() == '*') {
					text.setText(text.getText().replace('*', '×'));
//					text.setText(text.getText().substring(0, text.getText().length() - 1) + "×");
				}
				// 替换键盘'/'为'÷'
				if (e.getKeyChar() == '/') {
					text.setText(text.getText().replace('/', '÷'));
//					text.setText(text.getText().substring(0, text.getText().length() - 1) + "÷");
				}
			}
		});
	}

	// 按钮面板设置
	private void setPanel() {
		panel = new JPanel();
		panel.setOpaque(false);

		setButtons();
	}

	// 各按钮处理
	private void setButtons() {
		JButton btn0 = new JButton("0");
		btn0.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("0");
			}
		});

		JButton btn1 = new JButton("1");
		btn1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("1");
			}
		});

		JButton btn2 = new JButton("2");
		btn2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("2");
			}
		});

		JButton btn3 = new JButton("3");
		btn3.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("3");
			}
		});

		JButton btn4 = new JButton("4");
		btn4.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("4");
			}
		});

		JButton btn5 = new JButton("5");
		btn5.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("5");
			}
		});

		JButton btn6 = new JButton("6");
		btn6.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("6");
			}
		});

		JButton btn7 = new JButton("7");
		btn7.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("7");
			}
		});

		JButton btn8 = new JButton("8");
		btn8.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("8");
			}
		});

		JButton btn9 = new JButton("9");
		btn9.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("9");
			}
		});

		JButton btnNegate = new JButton("-/+");
		btnNegate.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (text.getText().startsWith("-")) {
					text.setText(text.getText().substring(1, text.getText().length()));
				} else {
					text.setText("-" + text.getText());
				}
			}
		});

		JButton btnDecimalPoint = new JButton(".");
		btnDecimalPoint.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append(".");
			}
		});

		JButton btnClean = new JButton("C");
		btnClean.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.setText("");
			}
		});

		JButton btnBack = new JButton("B");
		btnBack.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (!text.getText().isEmpty()) {
					text.setText(text.getText().substring(0, text.getText().length() - 1));
				}
			}
		});

		JButton btnAdd = new JButton("+");
		btnAdd.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("+");
			}
		});

		JButton btnSub = new JButton("-");
		btnSub.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("-");
			}
		});

		JButton btnMul = new JButton("×");
		btnMul.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("×");
			}
		});

		JButton btnDiv = new JButton("÷");
		btnDiv.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("÷");
			}
		});

		JButton btnRem = new JButton("%");
		btnRem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("%");
			}
		});

		JButton btnPow = new JButton("^");
		btnPow.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("^");
			}
		});

		JButton btnLeftBra = new JButton("(");
		btnLeftBra.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("(");
			}
		});

		JButton btnRightBra = new JButton(")");
		btnRightBra.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append(")");
			}
		});

		JButton btnEqual = new JButton("=");
		btnEqual.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				text.append("=");
				calculate();
			}
		});

		// 设置布局
		GroupLayout gl_panel = new GroupLayout(panel);
		gl_panel.setHorizontalGroup(gl_panel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panel.createSequentialGroup().addContainerGap().addGroup(gl_panel
						.createParallelGroup(Alignment.LEADING, false)
						.addGroup(gl_panel.createSequentialGroup()
								.addComponent(btnLeftBra, GroupLayout.PREFERRED_SIZE, 123, GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(ComponentPlacement.RELATED, 101, Short.MAX_VALUE)
								.addComponent(btnRightBra, GroupLayout.PREFERRED_SIZE, 117, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl_panel.createSequentialGroup().addGroup(gl_panel
								.createParallelGroup(Alignment.LEADING, false)
								.addComponent(btn1, GroupLayout.PREFERRED_SIZE, 111, GroupLayout.PREFERRED_SIZE)
								.addComponent(btnNegate, GroupLayout.PREFERRED_SIZE, 111, GroupLayout.PREFERRED_SIZE)
								.addComponent(btn7, GroupLayout.PREFERRED_SIZE, 111, GroupLayout.PREFERRED_SIZE)
								.addComponent(btn4, GroupLayout.PREFERRED_SIZE, 111, GroupLayout.PREFERRED_SIZE))
								.addGap(6)
								.addGroup(gl_panel.createParallelGroup(Alignment.LEADING, false)
										.addComponent(btn2, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE)
										.addComponent(btn0, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE)
										.addComponent(btn8, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 109,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(btn5, GroupLayout.PREFERRED_SIZE, 109,
												GroupLayout.PREFERRED_SIZE))
								.addPreferredGap(ComponentPlacement.RELATED)
								.addGroup(gl_panel.createParallelGroup(Alignment.LEADING, false)
										.addComponent(btn3, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE)
										.addComponent(btnDecimalPoint, GroupLayout.PREFERRED_SIZE, 109,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(
												btn9, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE)
										.addComponent(btn6, GroupLayout.PREFERRED_SIZE, 109,
												GroupLayout.PREFERRED_SIZE))))
						.addPreferredGap(ComponentPlacement.RELATED, 102, Short.MAX_VALUE)
						.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING).addGroup(gl_panel
								.createSequentialGroup()
								.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING, false)
										.addComponent(btnRem, GroupLayout.PREFERRED_SIZE, 116,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(btnMul, GroupLayout.PREFERRED_SIZE, 116,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(btnAdd, GroupLayout.PREFERRED_SIZE, 116,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(btnClean, Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 116,
												GroupLayout.PREFERRED_SIZE))
								.addGap(18)
								.addGroup(gl_panel.createParallelGroup(Alignment.LEADING, false)
										.addComponent(btnPow, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 116,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(btnDiv, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 116,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(btnSub, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 116,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(btnBack, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 116,
												GroupLayout.PREFERRED_SIZE)))
								.addGroup(gl_panel.createSequentialGroup().addComponent(btnEqual,
										GroupLayout.PREFERRED_SIZE, 182, GroupLayout.PREFERRED_SIZE).addGap(30)))
						.addContainerGap()));
		gl_panel.setVerticalGroup(
				gl_panel.createParallelGroup(Alignment.LEADING).addGroup(Alignment.TRAILING,
						gl_panel.createSequentialGroup().addGroup(gl_panel.createParallelGroup(Alignment.TRAILING)
								.addGroup(gl_panel.createSequentialGroup().addContainerGap().addGroup(gl_panel
										.createParallelGroup(Alignment.LEADING, false)
										.addComponent(btnClean, GroupLayout.PREFERRED_SIZE, 48,
												GroupLayout.PREFERRED_SIZE)
										.addComponent(
												btnBack, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 48,
												GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(ComponentPlacement.RELATED, 18, Short.MAX_VALUE)
										.addGroup(gl_panel.createSequentialGroup()
												.addGroup(gl_panel.createParallelGroup(Alignment.LEADING, false)
														.addComponent(btnAdd, GroupLayout.DEFAULT_SIZE,
																GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
														.addComponent(btnSub, GroupLayout.PREFERRED_SIZE, 35,
																GroupLayout.PREFERRED_SIZE))
												.addGap(18)
												.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
														.addComponent(btnMul, GroupLayout.PREFERRED_SIZE, 36,
																GroupLayout.PREFERRED_SIZE)
														.addComponent(btnDiv, GroupLayout.PREFERRED_SIZE, 37,
																GroupLayout.PREFERRED_SIZE))
												.addGap(18)
												.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE, false)
														.addComponent(btnRem, GroupLayout.PREFERRED_SIZE, 39,
																GroupLayout.PREFERRED_SIZE)
														.addComponent(btnPow, GroupLayout.PREFERRED_SIZE, 38,
																GroupLayout.PREFERRED_SIZE))
												.addGap(18).addComponent(btnEqual, GroupLayout.PREFERRED_SIZE, 44,
														GroupLayout.PREFERRED_SIZE)))
								.addGroup(gl_panel.createSequentialGroup()
										.addGroup(gl_panel.createParallelGroup(Alignment.LEADING, false)
												.addComponent(btnRightBra, GroupLayout.PREFERRED_SIZE, 48,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(btnLeftBra, GroupLayout.PREFERRED_SIZE, 48,
														GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(ComponentPlacement.RELATED, 60, Short.MAX_VALUE)
										.addGroup(gl_panel.createParallelGroup(Alignment.LEADING, false)
												.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE, false)
														.addComponent(btn2, GroupLayout.PREFERRED_SIZE, 35,
																GroupLayout.PREFERRED_SIZE)
														.addComponent(btn3, GroupLayout.PREFERRED_SIZE, 35,
																GroupLayout.PREFERRED_SIZE))
												.addComponent(btn1, GroupLayout.PREFERRED_SIZE, 35,
														GroupLayout.PREFERRED_SIZE))
										.addGap(18)
										.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE, false)
												.addComponent(btn4, GroupLayout.PREFERRED_SIZE, 39,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(btn5, GroupLayout.PREFERRED_SIZE, 39,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(btn6, GroupLayout.PREFERRED_SIZE, 39,
														GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(ComponentPlacement.RELATED)
										.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE, false)
												.addComponent(btn7, GroupLayout.PREFERRED_SIZE, 39,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(btn8, GroupLayout.PREFERRED_SIZE, 39,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(btn9, GroupLayout.PREFERRED_SIZE, 39,
														GroupLayout.PREFERRED_SIZE))
										.addGap(12)
										.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING, false)
												.addComponent(btnDecimalPoint, GroupLayout.PREFERRED_SIZE, 39,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(btn0, GroupLayout.PREFERRED_SIZE, 39,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(btnNegate, GroupLayout.PREFERRED_SIZE, 39,
														GroupLayout.PREFERRED_SIZE))))
								.addGap(35)));
		panel.setLayout(gl_panel);
	}

	// 主面板布局
	private void setContentLayout() {
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[] { 700, 0 };
		gridBagLayout.rowHeights = new int[] { 66, 308, 0 };
		gridBagLayout.columnWeights = new double[] { 1.0, Double.MIN_VALUE };
		gridBagLayout.rowWeights = new double[] { 1.0, 0.0, Double.MIN_VALUE };
		setLayout(gridBagLayout);

		GridBagConstraints gbc_text = new GridBagConstraints();
		gbc_text.fill = GridBagConstraints.BOTH;
		gbc_text.insets = new Insets(0, 0, 5, 0);
		gbc_text.gridx = 0;
		gbc_text.gridy = 0;
		add(text, gbc_text);

		GridBagConstraints gbc_panel = new GridBagConstraints();
		gbc_panel.fill = GridBagConstraints.BOTH;
		gbc_panel.gridx = 0;
		gbc_panel.gridy = 1;
		add(panel, gbc_panel);
	}

	// 计算算数表达式
	private void calculate() {
		try {
			text.append("\n");
			text.append(CalculatorUtils.calculate(text.getText()));
		} catch (CalculatorException.MathException me) {
			text.setText("");
			JOptionPane.showMessageDialog(null, "除数不能为0！", "提示消息", JOptionPane.WARNING_MESSAGE);
		} catch (CalculatorException.NullException ne) {
			text.setText("");
			JOptionPane.showMessageDialog(null, "您输入的表达式为空！", "提示消息", JOptionPane.WARNING_MESSAGE);
		} catch (CalculatorException.ExpressionException ee) {
			text.setText("");
			JOptionPane.showMessageDialog(null, "表达式错误！", "提示消息", JOptionPane.WARNING_MESSAGE);
		}
	}

	// 主面板美化
	@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

		g2d.setColor(new Color(255, 255, 255, 150));
		g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10);

		g2d.setColor(Color.pink);
		g2d.setStroke(new BasicStroke(4));
		g2d.drawRoundRect(0, 0, getWidth(), getHeight(), 10, 10);
	}
}